<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ECharts CSV 数据分析工具</title>
    <!-- 引入 ECharts -->
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
    <!-- 引入 Papa Parse 解析 CSV -->
    <script src="https://cdn.jsdelivr.net/npm/papaparse@5.4.1/papaparse.min.js"></script>
    <!-- 引入 Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- 引入 Font Awesome -->
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">

    <!-- 配置 Tailwind -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#3B82F6',
                        secondary: '#10B981',
                        accent: '#8B5CF6',
                        neutral: '#1F2937',
                        "base-100": '#F9FAFB',
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                },
            }
        }
    </script>

    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .chart-container {
                height: 400px;
            }
            .preview-container {
                max-height: 300px;
                overflow-y: auto;
            }
        }
    </style>
</head>
<body class="bg-base-100 text-neutral font-sans">
<div class="container mx-auto px-4 py-8">
    <header class="mb-8 text-center">
        <h1 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold text-primary mb-2">
            <i class="fa fa-bar-chart mr-2"></i>ECharts CSV 数据分析工具
        </h1>
        <p class="text-gray-600">上传 CSV 文件，立即生成数据可视化图表</p>
    </header>

    <main class="max-w-5xl mx-auto">
        <!-- 文件上传区域 -->
        <div class="bg-white rounded-xl shadow-lg p-6 mb-8 transform transition-all hover:shadow-xl">
            <div class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center cursor-pointer hover:border-primary transition-colors" id="dropArea">
                <input type="file" id="fileInput" class="hidden" accept=".csv">
                <i class="fa fa-cloud-upload text-4xl text-gray-400 mb-4"></i>
                <h3 class="text-xl font-semibold mb-2">拖放 CSV 文件到这里</h3>
                <p class="text-gray-500 mb-4">或者</p>
                <button class="bg-primary hover:bg-primary/90 text-white font-medium py-2 px-6 rounded-lg transition-all transform hover:scale-105 active:scale-95" id="browseBtn">
                    <i class="fa fa-folder-open mr-2"></i>浏览文件
                </button>
                <p class="text-gray-400 text-sm mt-4">支持的格式: .csv</p>
            </div>
        </div>

        <!-- 数据预览区域 -->
        <div id="dataPreview" class="hidden bg-white rounded-xl shadow-lg p-6 mb-8">
            <div class="flex flex-wrap justify-between items-center mb-6">
                <h2 class="text-xl font-bold text-neutral flex items-center">
                    <i class="fa fa-table mr-2 text-accent"></i>数据预览
                    <span id="fileName" class="ml-2 text-sm font-normal text-gray-500"></span>
                </h2>
                <div class="flex space-x-2 mt-2 sm:mt-0">
                    <select id="chartType" class="bg-gray-50 border border-gray-300 text-neutral rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary focus:border-primary">
                        <option value="line">折线图</option>
                        <option value="bar">柱状图</option>
                        <option value="pie">饼图</option>
                    </select>
                    <select id="xAxisField" class="bg-gray-50 border border-gray-300 text-neutral rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary focus:border-primary">
                        <option value="">X 轴字段</option>
                    </select>
                    <select id="yAxisField" class="bg-gray-50 border border-gray-300 text-neutral rounded-lg px-3 py-2 focus:ring-2 focus:ring-primary focus:border-primary">
                        <option value="">Y 轴字段</option>
                    </select>
                </div>
            </div>

            <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
                <!-- 数据统计信息 -->
                <div class="lg:col-span-1 bg-gray-50 rounded-lg p-4">
                    <h3 class="font-semibold mb-3 text-gray-700 flex items-center">
                        <i class="fa fa-info-circle mr-2 text-primary"></i>数据信息
                    </h3>
                    <div class="space-y-2 text-sm">
                        <div class="flex justify-between">
                            <span class="text-gray-500">记录数:</span>
                            <span id="recordCount" class="font-medium"></span>
                        </div>
                        <div class="flex justify-between">
                            <span class="text-gray-500">字段数:</span>
                            <span id="fieldCount" class="font-medium"></span>
                        </div>
                        <div class="flex justify-between">
                            <span class="text-gray-500">字段列表:</span>
                            <span id="fieldList" class="font-medium"></span>
                        </div>
                    </div>

                    <div class="mt-4">
                        <h3 class="font-semibold mb-3 text-gray-700 flex items-center">
                            <i class="fa fa-cogs mr-2 text-secondary"></i>图表配置
                        </h3>
                        <div class="space-y-3">
                            <div>
                                <label class="block text-sm font-medium text-gray-700 mb-1">标题</label>
                                <input type="text" id="chartTitle" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary" placeholder="图表标题">
                            </div>
                            <div class="flex items-center space-x-2">
                                <input type="checkbox" id="showLegend" class="rounded text-primary focus:ring-primary" checked>
                                <label for="showLegend" class="text-sm text-gray-700">显示图例</label>
                            </div>
                            <div class="flex items-center space-x-2">
                                <input type="checkbox" id="showTooltip" class="rounded text-primary focus:ring-primary" checked>
                                <label for="showTooltip" class="text-sm text-gray-700">显示提示框</label>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 数据表格预览 -->
                <div class="lg:col-span-2">
                    <div class="bg-white rounded-lg shadow-sm overflow-hidden">
                        <div class="preview-container overflow-x-auto">
                            <table id="dataTable" class="min-w-full divide-y divide-gray-200">
                                <thead class="bg-gray-50">
                                <tr id="tableHeader"></tr>
                                </thead>
                                <tbody id="tableBody" class="bg-white divide-y divide-gray-200"></tbody>
                            </table>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 图表区域 -->
            <div class="mt-8 bg-white rounded-lg shadow-sm overflow-hidden">
                <h3 class="font-semibold p-4 border-b border-gray-200 text-gray-700 flex items-center">
                    <i class="fa fa-area-chart mr-2 text-accent"></i>
                    <span id="currentChartTitle">数据可视化</span>
                </h3>
                <div class="p-2">
                    <div id="chartContainer" class="chart-container w-full"></div>
                </div>
            </div>
        </div>

        <!-- 无数据状态 -->
        <div id="noDataState" class="bg-white rounded-xl shadow-lg p-12 text-center">
            <i class="fa fa-file-text-o text-5xl text-gray-300 mb-4"></i>
            <h3 class="text-xl font-semibold text-gray-700 mb-2">尚未上传数据</h3>
            <p class="text-gray-500 mb-6">请上传 CSV 文件开始数据分析</p>
            <button class="bg-primary hover:bg-primary/90 text-white font-medium py-2 px-6 rounded-lg transition-all transform hover:scale-105 active:scale-95" id="uploadBtn">
                <i class="fa fa-upload mr-2"></i>上传 CSV 文件
            </button>
        </div>
    </main>

    <footer class="mt-12 text-center text-gray-500 text-sm">
        <p>© 2025 ECharts CSV 数据分析工具 | 使用 ECharts 和 Papa Parse 构建</p>
    </footer>
</div>

<script>
    // 全局变量
    let chart = null;
    let parsedData = null;
    let headers = [];

    // DOM 元素
    const dropArea = document.getElementById('dropArea');
    const fileInput = document.getElementById('fileInput');
    const browseBtn = document.getElementById('browseBtn');
    const uploadBtn = document.getElementById('uploadBtn');
    const dataPreview = document.getElementById('dataPreview');
    const noDataState = document.getElementById('noDataState');
    const fileName = document.getElementById('fileName');
    const recordCount = document.getElementById('recordCount');
    const fieldCount = document.getElementById('fieldCount');
    const fieldList = document.getElementById('fieldList');
    const tableHeader = document.getElementById('tableHeader');
    const tableBody = document.getElementById('tableBody');
    const chartType = document.getElementById('chartType');
    const xAxisField = document.getElementById('xAxisField');
    const yAxisField = document.getElementById('yAxisField');
    const chartTitle = document.getElementById('chartTitle');
    const showLegend = document.getElementById('showLegend');
    const showTooltip = document.getElementById('showTooltip');
    const currentChartTitle = document.getElementById('currentChartTitle');

    // 初始化图表
    function initChart() {
        const chartDom = document.getElementById('chartContainer');
        chart = echarts.init(chartDom);

        // 设置图表默认配置
        const option = {
            title: {
                text: '数据可视化',
                left: 'center'
            },
            tooltip: {
                trigger: 'axis'
            },
            legend: {
                top: 'bottom'
            },
            xAxis: {
                type: 'category',
                data: []
            },
            yAxis: {
                type: 'value'
            },
            series: [{
                name: '',
                type: 'line',
                data: []
            }]
        };

        chart.setOption(option);
    }

    // 解析 CSV 文件
    function parseCSV(file) {
        fileName.textContent = file.name;

        Papa.parse(file, {
            header: true,
            dynamicTyping: true,
            complete: function(results) {
                parsedData = results.data;
                headers = results.meta.fields;

                if (parsedData.length === 0) {
                    alert('CSV 文件中没有数据！');
                    return;
                }

                // 更新数据统计信息
                recordCount.textContent = parsedData.length;
                fieldCount.textContent = headers.length;
                fieldList.textContent = headers.join(', ');

                // 更新字段选择下拉框
                updateFieldSelectors();

                // 生成数据预览表格
                generatePreviewTable();

                // 默认使用第一个和第二个字段绘制图表
                if (headers.length >= 2) {
                    xAxisField.value = headers[0];
                    yAxisField.value = headers[1];
                    chartTitle.value = `${headers[1]} 随 ${headers[0]} 的变化`;
                    currentChartTitle.textContent = chartTitle.value;
                    renderChart();
                }

                // 显示数据预览区域，隐藏无数据状态
                dataPreview.classList.remove('hidden');
                noDataState.classList.add('hidden');
            },
            error: function(error) {
                console.error('CSV 解析错误:', error);
                alert('解析 CSV 文件时出错！');
            }
        });
    }

    // 更新字段选择下拉框
    function updateFieldSelectors() {
        // 清空现有选项
        xAxisField.innerHTML = '<option value="">X 轴字段</option>';
        yAxisField.innerHTML = '<option value="">Y 轴字段</option>';

        // 添加新选项
        headers.forEach(header => {
            const xOption = document.createElement('option');
            xOption.value = header;
            xOption.textContent = header;
            xAxisField.appendChild(xOption);

            const yOption = document.createElement('option');
            yOption.value = header;
            yOption.textContent = header;
            yAxisField.appendChild(yOption);
        });
    }

    // 生成预览表格
    function generatePreviewTable() {
        // 清空表格
        tableHeader.innerHTML = '';
        tableBody.innerHTML = '';

        // 添加表头
        headers.forEach(header => {
            const th = document.createElement('th');
            th.scope = 'col';
            th.className = 'px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider';
            th.textContent = header;
            tableHeader.appendChild(th);
        });

        // 添加数据行（最多显示 10 行）
        const rowsToShow = Math.min(parsedData.length, 10);
        for (let i = 0; i < rowsToShow; i++) {
            const row = parsedData[i];
            const tr = document.createElement('tr');
            tr.className = i % 2 === 0 ? 'bg-white' : 'bg-gray-50';

            headers.forEach(header => {
                const td = document.createElement('td');
                td.className = 'px-6 py-4 whitespace-nowrap text-sm text-gray-500';
                td.textContent = row[header] !== undefined ? row[header] : '';
                tr.appendChild(td);
            });

            tableBody.appendChild(tr);
        }

        // 如果数据超过 10 行，显示省略行
        if (parsedData.length > 10) {
            const tr = document.createElement('tr');
            const td = document.createElement('td');
            td.colSpan = headers.length;
            td.className = 'px-6 py-4 text-center text-sm text-gray-500';
            td.textContent = `... 还有 ${parsedData.length - 10} 行数据未显示`;
            tr.appendChild(td);
            tableBody.appendChild(tr);
        }
    }

    // 渲染图表
    function renderChart() {
        if (!parsedData || !xAxisField.value || !yAxisField.value) return;

        // 获取配置
        const selectedChartType = chartType.value;
        const selectedXField = xAxisField.value;
        const selectedYField = yAxisField.value;
        const title = chartTitle.value || `${selectedYField} 随 ${selectedXField} 的变化`;
        const shouldShowLegend = showLegend.checked;
        const shouldShowTooltip = showTooltip.checked;

        // 更新图表标题
        currentChartTitle.textContent = title;

        // 准备数据
        const xData = parsedData.map(row => row[selectedXField]);
        const yData = parsedData.map(row => row[selectedYField]);

        // 构建 ECharts 配置
        let option = {
            title: {
                text: title,
                left: 'center'
            },
            tooltip: {
                enabled: shouldShowTooltip,
                trigger: 'axis'
            },
            legend: {
                enabled: shouldShowLegend,
                top: 'bottom'
            },
            xAxis: {
                type: 'category',
                data: xData
            },
            yAxis: {
                type: 'value'
            },
            series: [{
                name: selectedYField,
                type: selectedChartType,
                data: yData,
                itemStyle: {
                    color: '#3B82F6'
                },
                emphasis: {
                    itemStyle: {
                        color: '#1D4ED8'
                    }
                }
            }]
        };

        // 如果是饼图，需要特殊配置
        if (selectedChartType === 'pie') {
            option = {
                title: {
                    text: title,
                    left: 'center'
                },
                tooltip: {
                    enabled: shouldShowTooltip,
                    trigger: 'item'
                },
                legend: {
                    enabled: shouldShowLegend,
                    type: 'scroll',
                    orient: 'vertical',
                    right: 10,
                    top: 20,
                    bottom: 20
                },
                series: [{
                    name: selectedYField,
                    type: 'pie',
                    radius: '50%',
                    data: parsedData.map(row => ({
                        value: row[selectedYField],
                        name: row[selectedXField]
                    })),
                    emphasis: {
                        itemStyle: {
                            shadowBlur: 10,
                            shadowOffsetX: 0,
                            shadowColor: 'rgba(0, 0, 0, 0.5)'
                        }
                    }
                }]
            };
        }

        // 应用配置到图表
        chart.setOption(option);
    }

    // 事件监听
    function setupEventListeners() {
        // 文件选择按钮
        browseBtn.addEventListener('click', () => {
            fileInput.click();
        });

        uploadBtn.addEventListener('click', () => {
            fileInput.click();
        });

        // 文件选择变化
        fileInput.addEventListener('change', (e) => {
            if (e.target.files.length > 0) {
                const file = e.target.files[0];
                if (file.type === 'text/csv' || file.name.endsWith('.csv')) {
                    parseCSV(file);
                } else {
                    alert('请选择 CSV 文件！');
                }
            }
        });

        // 拖放功能
        ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
            dropArea.addEventListener(eventName, preventDefaults, false);
        });

        function preventDefaults(e) {
            e.preventDefault();
            e.stopPropagation();
        }

        ['dragenter', 'dragover'].forEach(eventName => {
            dropArea.addEventListener(eventName, highlight, false);
        });

        ['dragleave', 'drop'].forEach(eventName => {
            dropArea.addEventListener(eventName, unhighlight, false);
        });

        function highlight() {
            dropArea.classList.add('border-primary');
            dropArea.classList.add('bg-blue-50');
        }

        function unhighlight() {
            dropArea.classList.remove('border-primary');
            dropArea.classList.remove('bg-blue-50');
        }

        dropArea.addEventListener('drop', handleDrop, false);

        function handleDrop(e) {
            const dt = e.dataTransfer;
            const file = dt.files[0];

            if (file && (file.type === 'text/csv' || file.name.endsWith('.csv'))) {
                parseCSV(file);
            } else {
                alert('请拖放 CSV 文件！');
            }
        }

        // 图表配置变化事件
        chartType.addEventListener('change', renderChart);
        xAxisField.addEventListener('change', renderChart);
        yAxisField.addEventListener('change', renderChart);
        chartTitle.addEventListener('input', renderChart);
        showLegend.addEventListener('change', renderChart);
        showTooltip.addEventListener('change', renderChart);

        // 窗口大小变化时重绘图表
        window.addEventListener('resize', () => {
            if (chart) {
                chart.resize();
            }
        });
    }

    // 初始化应用
    function initApp() {
        initChart();
        setupEventListeners();
    }

    // 页面加载完成后初始化应用
    document.addEventListener('DOMContentLoaded', initApp);
</script>
</body>
</html>